package cn.rocksolid.sport.assist.email;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;

import javax.annotation.PreDestroy;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import cn.rocksolid.sport.agency.entity.SmtpSettingEntity;
import cn.rocksolid.sport.assist.entity.EmailEntity;
import cn.rocksolid.sport.common.error.RSE;
import cn.rocksolid.sport.common.error.RockSolidException;
import cn.rocksolid.sport.common.task.ExecutorServiceUtils;

@Component
public class DefaultEmailSenderProvider implements EmailProvider {

  private static final String MAIL_SMTP_STARTTLS_ENABLED = "mail.smtp.starttls.enable";
  private static final String MAIL_SMTP_SSL_ENABLE = "mail.smtp.ssl.enable";

  private final ExecutorService es = ExecutorServiceUtils.init();

  @PreDestroy
  public void destroy() {
    ExecutorServiceUtils.destroy(es);
  }

  @Override
  public void sendSmtpEmail(SmtpSettingEntity smtpSettingEntity, EmailEntity emailEntity) {

    // 做个前置检查
    checkConfig(smtpSettingEntity);

    JavaMailSenderImpl javaMailSenderImpl = new JavaMailSenderImpl();
    javaMailSenderImpl.setDefaultEncoding(StandardCharsets.UTF_8.name());
    javaMailSenderImpl.setHost(smtpSettingEntity.getHost());
    javaMailSenderImpl.setPort(smtpSettingEntity.getPort());
    javaMailSenderImpl.setUsername(smtpSettingEntity.getUsername());
    javaMailSenderImpl.setPassword(smtpSettingEntity.getPassword());
    javaMailSenderImpl.setProtocol(JavaMailSenderImpl.DEFAULT_PROTOCOL);

    Properties mailProperties = new Properties();
    mailProperties.setProperty(MAIL_SMTP_STARTTLS_ENABLED, String.valueOf(smtpSettingEntity.getStarttls()));
    mailProperties.setProperty(MAIL_SMTP_SSL_ENABLE, String.valueOf(smtpSettingEntity.getSslEnable()));

    javaMailSenderImpl.setJavaMailProperties(mailProperties);

    MimeMessage mimeMessage = javaMailSenderImpl.createMimeMessage();

    try {
      MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
      mimeMessageHelper.setFrom(smtpSettingEntity.getEmail(), smtpSettingEntity.getSender());
      mimeMessageHelper.setTo(emailEntity.getReceivers());
      mimeMessageHelper.setSubject(emailEntity.getSubject());
      mimeMessageHelper.setText(emailEntity.getContent());
      // TODO: there will add attachments into current email
      es.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
          try {
            javaMailSenderImpl.send(mimeMessageHelper.getMimeMessage());
          } catch (Exception exp) {
            throw new RockSolidException(RSE.RS_TASK_FAIL, exp);
          }
          return null;
        }
      });
    } catch (MessagingException | UnsupportedEncodingException meuee) {
      throw new RockSolidException(RSE.INVALID_EMAILTEMP, meuee);
    }
  }

  private void checkConfig(SmtpSettingEntity setting) {
    if (null == setting) {
      throw new RockSolidException(RSE.INVALID_ES_CONF);
    }

    if (StringUtils.isBlank(setting.getHost()) || StringUtils.isBlank(setting.getUsername())
        || StringUtils.isBlank(setting.getPassword()) || null == setting.getPort()) {
      throw new RockSolidException(RSE.INVALID_ES_CONF);
    }
  }
}
